package com.geline.easytrans.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.geline.easytrans.annotation.DSMasked;
import com.geline.easytrans.enums.SensitiveStrategy;
import com.geline.easytrans.util.StringUtils;

import java.io.IOException;
import java.util.Objects;

/**
 * 序列化注解自定义实现
 * JsonSerializer<String>：指定String 类型，serialize()方法用于将修改后的数据载入
 * @author: mengxin
 * @date: 2023/4/13 10:58
 */
public class DSMaskedSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private SensitiveStrategy strategy;
    //新生成一个属性xxxShow显示原值
    private String newFieldName;
    private boolean isOriginName;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if(value==null){
            gen.writeNull();
            return;
        }
        SensitiveStrategy newStrategy = SensitiveStrategy.FULL;
        if(this.isOriginName){
            //在原字段中写入脱敏值
            if(strategy==null || strategy==SensitiveStrategy.AUTO){
                if(value.length()<=5){
                    newStrategy = SensitiveStrategy.SHORT;
                }else if(value.length()<=20){
                    newStrategy = SensitiveStrategy.MIDDLE;
                }else {
                    newStrategy = SensitiveStrategy.LONG;
                }
            }
            gen.writeString(newStrategy.desensitizer().apply(value));
        }else {
            //在当前字段写入值
            gen.writeString(value);
            if(strategy==null || strategy==SensitiveStrategy.AUTO){
                if(value.length()<=5){
                    newStrategy = SensitiveStrategy.SHORT;
                }else if(value.length()<=20){
                    newStrategy = SensitiveStrategy.MIDDLE;
                }else {
                    newStrategy = SensitiveStrategy.LONG;
                }
            }
            //在新字段中写入脱敏值
            gen.writeStringField(newFieldName, newStrategy.desensitizer().apply(value));
        }
    }

    /**
     * 获取属性上的注解属性
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        DSMasked annotation = property.getAnnotation(DSMasked.class);
        if (annotation!=null && Objects.equals(String.class, property.getType().getRawClass())) {
            this.strategy = annotation.strategy();
            String target = annotation.target();
            String fieldOrigin = property.getName();
            this.isOriginName = StringUtils.isBlank(target) ? true : fieldOrigin.equals(target);
            this.newFieldName = target;
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}
